<?php

namespace Xrfg\Api\Trading\Spot\Console;

use Illuminate\Support\Facades\Log;
use Throwable;
use Xrfg\Api\Trading\Spot\Events\Kline1SavedEvent;
use Xrfg\Api\Trading\Spot\Events\KlineSavedEvent;
use Xrfg\Core\Trading\Spot\Models\Kline as KlineModel;
use Illuminate\Console\Command;
use Xrfg\Core\Trading\Spot\Models\Pair;
use Xrfg\Api\Trading\Spot\Repositories\klineRepository;

class Kline extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'kline {type}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'K线统计';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $type = $this->argument('type');
        $closeTime = floor(time() / 60) * 60;
        $openTime = $closeTime - $type * 60;
        $pairs = Pair::whereIn('status', [Pair::STATUS_TRADING, Pair::STATUS_BREAK])->get();
        foreach ($pairs as $pair) {
            $symbol = $pair->symbol;
            $kline = new KlineModel($symbol, $type);
            try {
                // 当前时刻数据存在则不处理
                $isKlineExist = $kline->where('time_open', $openTime)->exists();
                if ($isKlineExist && $type != 1) {
                    continue;
                }

                // 取最近一条数据
                $last = (new KlineModel($symbol, $type))
                    ->orderBy('time_open', 'desc')
                    ->first();

                // 没有数据则不处理
                if (!$last) {
                    continue;
                }

                if (!$isKlineExist) {
                    $kline->time_open = $openTime;
                    $kline->time_close = $closeTime;
                    $kline->price_open = $last->price_close;
                    $kline->price_high = $last->price_close;
                    $kline->price_low = $last->price_close;
                    $kline->price_close = $last->price_close;
                    $kline->trades_number = 0;
                    $kline->trades_total = 0;
                    $kline->trades_count = 0;
                    $kline->save();

                    event(new KlineSavedEvent($kline));
                }

                // 每分钟更新一次ticker
                if (1 == $type) {
                    event(new Kline1SavedEvent($symbol));
                }
            } catch (Throwable $exception) {
                if ('42S02' == $exception->getCode()) {
                    (new KlineRepository())->createTable($kline->getTable());
                    $this->handle();
                } else {
                    Log::debug($exception);
                }
            }
        }
    }
}
